package com.base.component.ai.workflow.handle;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

import org.springframework.stereotype.Component;

import com.base.component.ai.agent.bo.ContextBO;
import com.base.component.ai.agent.bo.ContextParamBO;
import com.base.component.ai.workflow.core.InjectTypeEnum;
import com.base.component.ai.workflow.core.NodeHandle;
import com.base.component.ai.workflow.flow.Flow;
import com.base.component.ai.workflow.logs.NodeLog;
import com.base.component.ai.workflow.logs.NodeLogInject;
import com.base.component.ai.workflow.node.Node;
import com.base.component.ai.workflow.node.NodeInject;
import com.base.core.context.utils.SpringBeanUtils;
import com.gitee.magic.framework.base.utils.MapConvert;

@Component
public class NodeHandleInject<MSG,AP extends ContextParamBO,PP> implements NodeHandle<MSG,AP,PP>{
	
	@Override
	public <T extends Node> boolean support(Class<T> cls) {
		return cls.equals( NodeInject.class);
	}

	@Override
	public <T extends Node>List<Flow> execute(ContextBO<MSG,AP,PP> context,Map<String,Object> params,Flow flow,T node,Consumer<NodeLog> c) {
		NodeInject d=(NodeInject)node;
		Map<String,Object> pInject=new HashMap<>();
		for(String key:d.getInject().keySet()) {
			InjectTypeEnum injectType=d.getInject().get(key);
			if(injectType==InjectTypeEnum.CONTEXT) {
				Map<String,Object> p=new HashMap<>();
				p.put(key, params.get(key));
				pInject.put(key, params.get(key));
				Object obj=MapConvert.convert(context.getContextParam().getClass(), p);
				SpringBeanUtils.copyPropertiesIgnoreNull(obj, context.getContextParam());
			}else if(injectType==InjectTypeEnum.PROMPT) {
				Map<String,Object> p=new HashMap<>();
				p.put(key, params.get(key));
				pInject.put(key, params.get(key));
				Object obj=MapConvert.convert(context.getPromptParam().getClass(), p);
				SpringBeanUtils.copyPropertiesIgnoreNull(obj, context.getPromptParam());
			}else if(injectType==InjectTypeEnum.PAYLOAD) {
				pInject.put(key, params.get(key));
				context.getPayload().put(key, params.get(key));
			}
		}
		
		NodeLogInject nodeLog=new NodeLogInject();
		nodeLog.setInjectData(pInject);
		c.accept(nodeLog);
		
		return flow.getNexts();
	}
	
}
